using System;
using System.Collections.Generic;
using System.Text;
using JobShopModel.Model.FactoryLvl;

namespace JobShopModel.Model.Job
{
    class Jobs:JobShopModel.Events.IEvent

    {
        private Time startTime;
        private Time finishTime;
        public JobShopModel.Extern.Exponential exp = new JobShopModel.Extern.Exponential();

        public Time StartTime
        {
            get { return startTime; }
        }
       
        public Time FinishTime
        {
            get { return finishTime; }
            set { finishTime = value; }
        }

        private List<Operation> listOperation;

        private void addOperation(StationsList station,Time time)
        {
            listOperation.Add(new Operation(station,time));
        }

        public Operation getNexOperation()
        {
            Operation rtn = null;
            foreach (Operation o in listOperation)
            {
                if (o.Status == OperationStatus.UNDONE)
                {
                    rtn = o;
                    break;
                }
            }
            return rtn;
        }

        /// <summary>
        /// Private constructor.
        /// </summary>
        private Jobs(Time start)
        {
            this.startTime = start;
            this.listOperation = new List<Operation>();
        }


        public static Jobs CreateJob(JobsTypes type)
        {
            Jobs tmp = new Jobs(Factory.getInstance().CurrentTime);
            //tmp.StartTime.Hours = tmp.expRandom(.25);
            //creates a new job with start time equal to the current time, then increment the start time's
            //hour value by an exponential random variable with mean .25 (as stated in the spec)

            switch (type)
            {
                case JobsTypes.JOB1:
                   
                    //tmp.addOperation(StationsList.STATION3, new Time(0,0.50));
                    tmp.addOperation(StationsList.STATION3, new Time(0,tmp.exp.calculate(.25)+tmp.exp.calculate(.25)));
                    //tmp.addOperation(StationsList.STATION1, new Time(0,0.60));
                    tmp.addOperation(StationsList.STATION1, new Time(0, tmp.exp.calculate(.3) + tmp.exp.calculate(.3)));
                    //tmp.addOperation(StationsList.STATION2, new Time(0,0.85));
                    tmp.addOperation(StationsList.STATION2, new Time(0, tmp.exp.calculate(.425) + tmp.exp.calculate(.425)));
                    //tmp.addOperation(StationsList.STATION5, new Time(0.50));
                    tmp.addOperation(StationsList.STATION5, new Time(0, tmp.exp.calculate(.25) + tmp.exp.calculate(.25)));
                    tmp.addOperation(StationsList.IOSTATION, new Time(0.00));

                    break;

                case JobsTypes.JOB2:

                    //tmp.addOperation(StationsList.STATION4, new Time(1.10));
                    tmp.addOperation(StationsList.STATION4, new Time(0, tmp.exp.calculate(.55) + tmp.exp.calculate(.55)));
                    //tmp.addOperation(StationsList.STATION1, new Time(0.80));
                    tmp.addOperation(StationsList.STATION1, new Time(0, tmp.exp.calculate(.4) + tmp.exp.calculate(.4)));
                    //tmp.addOperation(StationsList.STATION3, new Time(0.75));
                    tmp.addOperation(StationsList.STATION3, new Time(0, tmp.exp.calculate(.375) + tmp.exp.calculate(.375)));
                    tmp.addOperation(StationsList.IOSTATION, new Time(0.00));

                    break;

                case JobsTypes.JOB3:

                    //tmp.addOperation(StationsList.STATION2, new Time(1.20));
                    tmp.addOperation(StationsList.STATION2, new Time(0, tmp.exp.calculate(.6) + tmp.exp.calculate(.6)));
                    //tmp.addOperation(StationsList.STATION5, new Time(0.25));
                    tmp.addOperation(StationsList.STATION5, new Time(0, tmp.exp.calculate(.125) + tmp.exp.calculate(.125)));
                    //tmp.addOperation(StationsList.STATION1, new Time(0.70));
                    tmp.addOperation(StationsList.STATION1, new Time(0, tmp.exp.calculate(.35) + tmp.exp.calculate(.35)));
                    //tmp.addOperation(StationsList.STATION4, new Time(0.90));
                    tmp.addOperation(StationsList.STATION4, new Time(0, tmp.exp.calculate(.45) + tmp.exp.calculate(.45)));
                    //tmp.addOperation(StationsList.STATION3, new Time(1.00));
                    tmp.addOperation(StationsList.STATION3, new Time(0, tmp.exp.calculate(.5) + tmp.exp.calculate(.5)));
                    tmp.addOperation(StationsList.IOSTATION,new Time(0.00));

                    break;

            }

            return tmp;
        }
        public new void fire()
            //occurs when job begins or ends
        {
            if (Factory.getInstance().CurrentTime == startTime)
            //Job is starting
            {
                //add time job will finish to event queue
            }
        }

        //This function takes as a parameter the mean of an exponential distribution and
        //returns a value from the distribution
        /*private double expRandom(double mean)
        {
            Random rand = new Random();
            double randDouble = rand.NextDouble();
            randDouble += 1.0;
            randDouble /= 2.0;
            //have to increase value because NextDouble can return 0 and log(0) is undefined,
            //then divide by 2 (1 is the maximum of NextDouble and we added 1), giving a random double
            //strictly greater than 0 and less than or equal to 1
            return (-1) * Math.Log(randDouble, Math.E) / mean;
        }*/

    }
}
